package org.eclipse.moquette.server;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.text.ParseException;
import java.util.Map;
import java.util.Properties;

import static org.eclipse.moquette.commons.Constants.*;

/**
 * 解析配置文件
 * Created by alex on 15-5-29.
 */
public class ConfigurationParser {

    private static final Logger LOG = LoggerFactory.getLogger(ConfigurationParser.class);

    //创建配置对象
    private Properties m_properties = new Properties();

    ConfigurationParser() {
        createDefaults();
    }

    ConfigurationParser(Properties properties) {
        this();
        for (Map.Entry<Object, Object> entrySet : properties.entrySet()) {
            m_properties.put(entrySet.getKey(), entrySet.getValue());
        }
    }

    //初始化默认属性
    private void createDefaults() {
        m_properties.put(PORT_PROPERTY_NAME, Integer.toString(PORT));
        m_properties.put(HOST_PROPERTY_NAME, HOST);
        m_properties.put(WEB_SOCKET_PORT_PROPERTY_NAME, Integer.toString(WEBSOCKET_PORT));
        m_properties.put(PASSWORD_FILE_PROPERTY_NAME, "");
        m_properties.put(PERSISTENT_STORE_PROPERTY_NAME, DEFAULT_PERSISTENT_PATH);
        m_properties.put(ALLOW_ANONYMOUS_PROPERTY_NAME, true);
    }

    //解析配置文件
    void parse(File file) throws ParseException {
        if (file == null){
            LOG.warn("Parsing NULL file, so fallback on default configuration");
            return;
        }

        if (!file.exists()) {
            LOG.warn(String.format("parsing not existing file %s, so fallback on default configuration!", file.getAbsolutePath()));
            return;
        }

        try {
            FileReader reader = new FileReader(file);
            parse(reader);
        } catch (FileNotFoundException fex){
            LOG.warn(String.format("parsing not existing file %s, so fallback on default configuration!", file.getAbsolutePath()), fex);
            return;
        }
    }

    /**
     * 解析配置文件具体方法
     * @param reader
     * @throws ParseException
     */
    void parse(Reader reader) throws ParseException {

        if (reader == null) {
            //just log and return default properties
            LOG.warn("parsing NULL reader, so fallback on default configuration!");
            return;
        }

        BufferedReader br = new BufferedReader(reader);
        String line;

        try {
            while ((line = br.readLine()) != null) {
                //不能包含'#'
                int commentMarker = line.indexOf('#');
                if (commentMarker != -1) {
                    if (commentMarker == 0) {
                        continue;
                    }else {
                        throw new ParseException(line, commentMarker);
                    }
                } else {
                    //忽略空白行
                    if (line.isEmpty() || line.matches("^\\s*$")) {
                        continue;
                    }

                    parseWithSpace(line);
                }
            }
        } catch (IOException e) {
            throw new ParseException("Failed to read", 1);
        }
    }

    /**
     * 中间使用空白间隔
     * @param line
     */
    private void parseWithSpace(String line) {
        int deilimiterIdx = line.indexOf(' ');
        String key = line.substring(0, deilimiterIdx).trim();
        String value = line.substring(deilimiterIdx).trim();

        m_properties.put(key, value);
    }

    Properties getProperties() {
        return m_properties;
    }
}
